package com.hts.exception;


import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author hs
 * @version 1.0
 * @date: 2022/12/8
 */
@Data
public class CustomException extends RuntimeException {

    public static final String ERR_LOG = "错误原因：{}，错误内容：{}";
    private static final int BASE = 10000000;
    private int code = 500;

    private String message;
    /**
     * 栈的信息封装
     */
    private String stackInformation;

    private static final String BASE_BUSINESS_PAGE_NAME="com.cx.bid.opening";
    public CustomException(int code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }

    public CustomException(int code, String message, String stackInformation) {
        super(message);
        this.code = code;
        this.message = message;
        this.stackInformation = stackInformation;
    }

    /**
     * 对异常封装处理
     * @param e
     */
    public CustomException(Exception e) {
        super(e.getMessage());
        this.code = getUnKnowCode();
        this.message = e.getMessage();
        this.stackInformation = getExceptionStackInfo(e,BASE_BUSINESS_PAGE_NAME);
    }

    /**
     * 获取栈的信息数据
     * @param e
     * @return
     */
    public static String getExceptionBidOpenInfoStackInfo(Exception e) {
        return getExceptionStackInfo(e,BASE_BUSINESS_PAGE_NAME);
    }
    public static String getExceptionStackInfo(Exception e,String filterPageName) {
        StackTraceElement[] stackTrace = e.getStackTrace();

        return Arrays.stream(stackTrace).map(StackTraceElement::toString).filter(s -> !StringUtils.hasText(filterPageName) || s.contains(filterPageName)).collect(Collectors.joining("\n"));
    }

    public CustomException(CustomExceptionEnum customExceptionEnum) {
        this(BASE + customExceptionEnum.getCode(), customExceptionEnum.getMessage());
    }

    public CustomException(String message) {
        super(message);
        this.message = message;
    }


    public CustomException(String message, Object... messages) {
        super(formatMessage(message, messages));
        this.message = super.getMessage();
    }


    public static String formatMessage(String message, Object... messages) {
        for (Object o : messages) {
            message = message.replaceFirst("\\{\\}", o instanceof String ? o.toString() : JSONObject.toJSONString(o));
        }
        return message;
    }

    public static Supplier<CustomException> getError(String message) {
        return () -> new CustomException(message);
    }

    public static CustomException notFind() {
        return new CustomException(CustomExceptionEnum.NOT_FIND);
    }

    public static CustomException dataError() {
        return new CustomException(CustomExceptionEnum.DATA_ERROR);
    }

    public static CustomException sectionNotFind() {
        return new CustomException(CustomExceptionEnum.SECTION_NOT_FIND);
    }

    public static CustomException sectionInfoError() {
        return new CustomException(CustomExceptionEnum.SECTION_INFO_ERROR);
    }

    public static CustomException proNotError() {
        return new CustomException(CustomExceptionEnum.PRO_NOT_ERROR);
    }

    public static CustomException proNotFind() {
        return new CustomException(CustomExceptionEnum.PRO_NOT_FIND);
    }

    public static CustomException templeNotFind() {
        return new CustomException(CustomExceptionEnum.TEMPLE_NOT_FIND);
    }

    public static CustomException fileNotFind() {
        return new CustomException(CustomExceptionEnum.FILE_NOT_FIND);
    }

    public static CustomException outlineNotFind() {
        return new CustomException(CustomExceptionEnum.OUTLINE_NOT_FIND);
    }

    public static CustomException signFileTypeNotFind() {
        return new CustomException(CustomExceptionEnum.SIGN_FILE_TYPE_NOT_FIND);
    }

    public static int getUnKnowCode() {
        return BASE + CustomExceptionEnum.UNKNOWN_EXCEPTION.getCode();
    }

    @Getter
    @AllArgsConstructor
    public static enum CustomExceptionEnum {
        UNKNOWN_EXCEPTION(9999, "操作异常"),

        NOT_FIND(1001, "未找到数据"),
        DATA_ERROR(1002, "数据有误"),
        DATA_REPEAT_SUBMIT(1003, "数据重复提交"),
        DO_NOT_REPEAT_THE_OPERATION(1003, "请勿重复操作"),
        SYSTEM_BUSY(1004, "服务器繁忙"),

        SECTION_NOT_FIND(2001, "标段信息找不到"),
        SECTION_INFO_ERROR(2002, "标段信息关联数据有误"),


        PRO_NOT_FIND(3001, "项目信息未找到"),
        PRO_NOT_ERROR(3002, "项目信息有误"),

        TEMPLE_NOT_FIND(4001, "模板信息未找到"),


        FILE_NOT_FIND(5001, "未找到文件"),

        OUTLINE_NOT_FIND(6001, "未找到大纲文件"),
        SIGN_FILE_TYPE_NOT_FIND(8001, "签章类型未找到"),


        ;

        private final int code;

        private final String message;
    }
}
